import ujson
import _thread
import app_adc
import app_network
import app_config
import app_server
import _thread
import os
from umqtt.simple import MQTTClient
import time
import machine
import ubinascii
import app_relay
import app_ota
import app_sensor

mqtt_state = 0
global server_update_rc
server_update_rc = -1
global loop_ret
global reply_payloads
global port_reply
port_reply = 0
global order_reply
order_reply = 0
global reply_type
reply_type = 0
global reply_1min
reply_1min = 0
global post_reply
post_reply = 0
reply_1min = 0
flag_launch = 0  
sensorstate=False
#上线原因 默认断电重启 0断电重启，1断网重连
global onreason
onreason = 0
global ota_flag
ota_flag = 0
global ota_sleep
ota_sleep = 0
sleep_state = False
timingtime=0
read_key=1



#获取mqtt连接状态
def mqtt_get_server_state():
    global mqtt_state
    return mqtt_state

#设置mqtt连接状态
def mqtt_set_server_state(value):
    global mqtt_state
    mqtt_state = value



reread_cfg = False
def reread_cfg_state():
    global reread_cfg
    return reread_cfg

def set_reread_cfg_state(state):
    global reread_cfg
    reread_cfg = state


#获取cfg的mqtt信息
def get_cfg_data(data):
    global qos2,hearttime
    global deviceCode,serveraddr,serverport,deviceSecret,deviceKey
    global get_topic,post_topic
    global senstype,sensor_modle,resheart
    qos2 = int(data["mqtt_lte"]["qos1"])
    # deviceCode=data["mqtt_lte"]["deviceCode"]
    hearttime=int(data["hearttime"])
    serveraddr=data["mqtt_lte"]["serveraddr"]
    serverport=int(data["mqtt_lte"]["serverport"])
    deviceSecret=data["mqtt_lte"]["deviceSecret"]
    deviceKey= data["mqtt_lte"]["deviceKey"]
    senstype=data["senstype"]
    resheart= data["resheart"]
    sensor_modle =data["sensmodel"]


#回复检测
def reply_detect():
    global reply_payloads
    global reply_type
    # print("---------------reply_type={}".format(reply_type))
    # if reply_type == 1:
    #     reply_type = 0
    #     reply_payloads = update_reply_charge(port_reply,order_reply)   # 发布服务
    #     server_update(reply_payloads)  
    if reply_type == 2:
        reply_type = 0
        reply_payloads = update_reply_other()   # 发布服务
        print("reply_payloads:",reply_payloads)
        server_update(reply_payloads) 


#定时上报传感器数据
def mqtt_timing_update_data():
    print("----------------enter timing_update_data in mqtt")
    payloads = update_regular_report_data()
    server_update(payloads)  #定时上报端口数据
    print(payloads)
    

#mqtt服务发布
def server_update(payloads):
    global mqtt_state
    global post_topic
    global qos2
    global server_update_rc
    print("server_update_mqtt_state:",mqtt_state) 
    # print("post_topic",post_topic)
    if mqtt_state == 1:
        global client
        try:
            server_update_rc = client.publish(topic=post_topic, msg = payloads, retain=False,qos=0)
            print("publish return ={}\n".format(server_update_rc))
        except:
            try:
                server_update_rc = client.publish(topic=post_topic, msg = payloads, retain=False,qos=0)
                print(" publish return ={}\n".format(server_update_rc))
            except:
                mqtt_state = 0
                print(" server disconnect")
    else:
        print(" server disconnect!")
        return 1
       

def mqtt_ota_app_detec():
    global ota_flag,ota_version,ota_sleep
    global ota_url
    if ota_flag == 1:
        ota_flag = 0
        app_ota.ota_py(ota_url)
    else:
        pass

    if ota_flag == 2:
        ota_flag = 0
        app_ota.ota_pac()
    else:
        pass

  
# 定义subcribe的回调函数
def on_subcribe(topic,msg):
    global reread_cfg,sleep_state
    global yue_flag
    global ota_version
    global ota_flag,ota_sleep
    global ota_url
    global port_reply
    global order_reply
    global reply_type
    global post_reply
    ota_version = "1.00"
    yue_flag = 0
    data = ((topic, msg))
    # print(data)
    payload = data[1]
    print('payload:',payload,type(payload))
    try:
        cloudmsg = ujson.loads(payload)
    except Exception :
         print("this is not json type!!!")
    else:
        if isinstance(cloudmsg,dict):                 #检查收到的数据是否是标准的json格式
            if "switch1" in cloudmsg:          #平台下发继电器开关
                if cloudmsg["switch1"]==1:
                    app_relay.relay_ctl(1,1)
                elif cloudmsg["switch1"]==0:
                    app_relay.relay_ctl(1,0)
            if "switch2" in cloudmsg:          #平台下发继电器开关
                if cloudmsg["switch2"]==1:
                    app_relay.relay_ctl(2,1)
                elif cloudmsg["switch2"]==0:
                    app_relay.relay_ctl(2,0)
                reply_type = 2
            if "method" in cloudmsg:          #平台设置
                if "service.set" in cloudmsg["method"]:
                    params = cloudmsg["params"]
                    #print("set param_msg {}".format(params))
                    paramsmsg = cloudmsg.get("params")
                    print("param_msg {}".format(paramsmsg))
                    print("----------------------------------0")
                    if "setdata" in paramsmsg:       #配置参数指令
                        setdata_msg = paramsmsg.get("setdata")
                        if "netmode" in setdata_msg:
                            app_config.write_cfg({"netmode":setdata_msg["netmode"]})
                            time.sleep_ms(200)
                            machine.reset()
                            
                        if "hearttime" in setdata_msg:
                            app_config.write_cfg({"hearttime":setdata_msg["hearttime"]})

                        if "resheart" in setdata_msg:
                            app_config.write_cfg({"resheart":setdata_msg["resheart"]})

                        if "reporttime" in setdata_msg:
                            app_config.write_cfg({"reporttime":setdata_msg["reporttime"]})

                        if "nettype" in setdata_msg:
                            app_config.write_cfg({"nettype":setdata_msg["nettype"]})

                        if "apn" in setdata_msg:
                            app_config.write_cfg({"apn":setdata_msg["apn"]})   
                        reply_type = 2                   
                        reply_detect()
                        reread_cfg = True

                    elif "serverpar" in paramsmsg:       #配置服务器参数指令
                        setdata_msg = paramsmsg.get("serverpar")
                        if "serveraddr" in setdata_msg and "serverport" in setdata_msg:
                            if "serveraddr" in setdata_msg:
                                app_config.write_cfg({"serveraddr":setdata_msg["serveraddr"]})
                            if "serverport" in setdata_msg:
                                app_config.write_cfg({"serverport":setdata_msg["serverport"]})
                            if "qos1" in setdata_msg:
                                app_config.write_cfg({"qos1":setdata_msg["qos1"]})
                            if "deviceCode" in setdata_msg:
                                app_config.write_cfg({"deviceCode":setdata_msg["deviceCode"]})
                            if "deviceSecret" in setdata_msg:
                                app_config.write_cfg({"deviceSecret":setdata_msg["deviceSecret"]})
                            if "deviceKey" in setdata_msg:
                                app_config.write_cfg({"deviceKey":setdata_msg["deviceKey"]})
                            time.sleep_ms(200)
                            machine.reset()

                    elif "setsensor" in paramsmsg:       #配置传感器数据
                        setdata_msg = paramsmsg.get("setsensor")
                        print("setsensor in paramsmsg")
                        app_config.write_cfg(setdata_msg)
                        reply_type = 2
                        reply_detect()
                        reread_cfg = True

                elif "service.askdata" in cloudmsg["method"]:   #平台查询终端上报信息
                    params = cloudmsg["params"]
                    # immed_report = 1
                    payloads = update_regular_report_data()
                    print("payloads",payloads,"\n")
                    server_update(payloads)  
                    print("askdata param_msg {}".format(params)) 
                    reply_type = 2
                    
                elif "service.reboot" in cloudmsg["method"]:          #终端重启
                    params = cloudmsg["params"]
                    time.sleep_ms(200)
                    machine.reset()
                    
                elif "service.hota" in cloudmsg["method"]:          #固件升级-py
                    paramsmsg = cloudmsg["params"]
                    ota_version = "1.00"
                    binsize = 0
                    ota_url = ""
                    ota_version = 0
                    print("hota param_msg {}".format(paramsmsg)) 
                    if "size" in paramsmsg:          #固件大小
                        binsize = int(paramsmsg["size"])
                    if "sign" in paramsmsg:          #
                        binsign = paramsmsg["sign"]
                    if "version" in paramsmsg:          #版本号
                        ota_version = paramsmsg["version"]
                    if "url" in paramsmsg:          #地址
                        ota_url = paramsmsg["url"]
                        print("-----------------ota_url={}".format(ota_url))
                    if "md5" in paramsmsg:          #
                        md5 = paramsmsg["md5"]
                    if binsize > 0 and binsize <= 250000:  #250k限制
                        ota_flag = 1
                        ota_sleep = 1
                        print("---------------ota_flag=1")
                    reply_type = 2
                elif "service.pacota" in cloudmsg["method"]:          #固件升级-pac
                    paramsmsg = cloudmsg["params"]
                    ota_version = "1.00"
                    binsize = 0 
                    ota_url = ""
                    ota_version = 0
                    print("hota param_msg {}".format(paramsmsg)) 
                    if "size" in paramsmsg:          #固件大小
                        binsize = int(paramsmsg["size"])
                    if "sign" in paramsmsg:          #
                        binsign = paramsmsg["sign"]
                    if "version" in paramsmsg:          #版本号
                        ota_version = paramsmsg["version"]
                    if "url" in paramsmsg:          #地址
                        ota_url = paramsmsg["url"]
                        print("-----------------ota_url={}".format(ota_url))
                    if "md5" in paramsmsg:          #
                        md5 = paramsmsg["md5"]
                    if binsize > 0 and binsize <= 1000000:  #1000k限制
                        ota_flag = 2
                        ota_sleep = 2
                        print("---------------ota_flag={}".format(ota_flag))
                    reply_type = 2

                elif "service.reply" in cloudmsg["method"]:         #平台回复
                    paramsmsg = cloudmsg.get("params")
                    if "login" in paramsmsg:
                        login_msg=paramsmsg.get("login")
                        if "state" in login_msg:
                            #为1说明收到下行数据中的 state
                            post_reply=1
                            print("post_reply",post_reply)
                            # state=login_msg["state"]
                            reply_type = 0
            else :
                pass
        else:
            print("is not json data!")


#mqtt数据接收监测
def mqttloop_func(delay, id):
    global onreason
    global client
    global mqtt_state
    global post_reply
    n= 0
    while True:
        time.sleep_ms(delay)
        try:
            n+=1
            client.check_msg()
            # print(n)
            if n>=10:
                client.ping()
                n = 0
                print('ping')
        except:
            print("-------------------------------------------mqtt disconnect!")
            post_reply=0
            onreason = 1  #第一次开机原因是上电，其他都是属于断网重连
            mqtt_state = 0
            try:
                client.disconnect()
            except:
                print('dis')
            try:
                mqtt_reconnect()
            except:
                print('rec')


#mqtt重新连接
def mqtt_reconnect():
    global qos2,hearttime,resheart
    global serveraddr,serverport,deviceSecret,deviceKey,sleep_state
    global get_topic
    global post_topic
    global client,mqtt_state,sensorstate,imei
    # client_id = ubinascii.hexlify(machine.unique_id())
    # print('client_id',client_id)
    print(imei, serveraddr, serverport, deviceSecret, deviceKey, hearttime)
    client = MQTTClient(imei, serveraddr, serverport, deviceSecret, deviceKey, hearttime) 
    client.set_callback(on_subcribe)
    try:
        client.connect()    #平台连接失败会报错
        mqtt_state= 1
        print("mqtt_reconnect",mqtt_state)
        client.subscribe(get_topic)
        payloads = update_regular_report_data()
        print("payloads",payloads,"\n")
        server_update(payloads)  
    except:
        mqtt_state = 0
        print('mqtt_fail',mqtt_state)

        
#mqtt首次连接
def mqtt_connect():
    global imei,iccid,version
    global get_topic,post_topic
    print('mqtt---------------')
    imei = ''.join(map(lambda x: '%02x' % x, machine.unique_id()))
    if app_network.get4gFlag():
        version,iccid = app_network.get_4g_info()
    else:
        iccid = ''
        version = ''
    # print(imei) 
    get_topic = "attributes/push" 
    post_topic = "attributes"
    mqtt_reconnect()
    _thread.start_new_thread(mqttloop_func,(1500, 1))  #创建mqtt接收数据任务，1s一次
    # payloads = update_power_on_data()

def update_regular_report_data(): 
    global iccid,version,powvol,onreason,imei
    powvol=app_adc.get_ai_3_value()
    humidity,cTemp=app_sensor.get_uart_data()
    di1,di2 = app_sensor.get_di_data()
    ai1,ai2 = app_sensor.get_ai_data()
    send_data = {
        "method":"service.post",
        "id":imei,
        "hum":humidity,
        "temp":cTemp,
        "powvol":powvol,
        "di1":di1,
        "di2":di2,
        "ai1":ai1,
        "ai2":ai2
    }
    MSG = ujson.dumps(send_data)
    print("exit update_regular_report_data ")
    return MSG   
 

#配置回复
def update_reply_other():
    global imei 
    send_data = {
        "method":"device.reply",
        "id":imei,
        "params" :{}
        }
    MSG = ujson.dumps(send_data)
    return MSG    


